package com.Shuang.Frame;

import com.Shuang.Appoint.Appointment;
import com.Shuang.Hospital.Department;
import com.Shuang.Hospital.Doctor;
import com.Shuang.Hospital.Schedule;

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.UUID;

public class HospitalManager {
    ArrayList<Department> departments = new ArrayList<>();  //医院有很多科室
    ArrayList<Appointment> appointments = new ArrayList<>();  //有很多预约信息
    Scanner sc = new Scanner(System.in);
    //医院系统的欢迎界面
    public void start(){
        while (true) {
            System.out.println("~~~欢迎来到医院管理系统~~~");
            System.out.println("1、科室管理-增加科室~");
            System.out.println("2、科室管理-删除科室~");
            System.out.println("3、科室管理-修改科室~");
            System.out.println("4、医生管理-添加医生~");
            System.out.println("5、医生管理-添加医生排班信息~");  //（设置当天和未来六天的排班信息）
            System.out.println("6、医生管理-展示全部医生的排班信息~");  //（全部医生当天和未来六天的排班信息）
            System.out.println("7、医生管理-挂号预约~");
            System.out.println("8、搜索某个医生当天和未来六天病人的预约详情~");  //展示每天预约病人的具体信息
            System.out.println("请输入您要选择的指令：");
            String  command = sc.next();
            switch (command){
                case "1":
                    addDepartment();
                    break;
                case "2":
//                    delDepartment();
                    break;
                case "3":
//                    updateDepartment();
                    break;
                case "4":
                    addDoctor();
                    break;
                case "5":
                    addDoctorSchedule();
                    break;
                case "6":
                    showDoctorSchedule();
                    break;
                case "7":
//                    appointDoctor();
                    break;
                case "8":
//                    searchDoctorAppointment();
                    break;
                default:
                    System.out.println("您输入的命令有误~请重新输入喔~");
            }
        }
    }

    //展示全部医生排班情况
    private void showDoctorSchedule() {
        for (int i = 0; i < departments.size(); i++) {
            Department department = departments.get(i);
            System.out.println((i + 1) + "、" + department.getName());
            System.out.println("---------------------------------");
            for (int j = 0; j < department.getDoctors().size(); j++) {
                Doctor doctor = department.getDoctors().get(j);
                System.out.println((j + 1) + "、" + doctor.getName());
                ArrayList<Schedule> schedules = doctor.getSchedules();
                updateSchedule(schedules);  //更新排班表，保证查的时候始终是当天和未来6天的排班信息
                for (int k = 0; k < schedules.size(); k++) {
                    Schedule schedule = schedules.get(k);
                    System.out.println(schedule.getToday());
                    if (!schedule.isUpdate()){
                        System.out.println("未排班~");
                        continue;
                    }
                    System.out.println("上午：");
                    if (schedule.isMorning()){
                        System.out.println("坐诊时间为" + schedule.getMstart() + "-" + schedule.getMend()
                                + "可预约总数/已预约" + schedule.getmAppointTotalNumber() + "/" + schedule.getmAppointNumer());
                    }else{
                        System.out.println("休息中~");
                        }
                    System.out.println("下午：");
                    if (schedule.isAfternoon()){
                        System.out.println("坐诊时间为" + schedule.getAstart() + "-" + schedule.getAend()
                                + "可预约总数/已预约" + schedule.getaAppointTotalNumber() + "/" + schedule.getaAppointNumer());
                    }else{
                        System.out.println("休息中~");
                        }
                    System.out.println("--------------------------");
                }
            }
        }
    }

    //对医生进行排班
    private void addDoctorSchedule() {
        System.out.println("~~为医生设置坐诊信息~~");
        //通过用户选择科室
        Department departmentByUser = getDepartmentByUser();
        if (departmentByUser == null){
            return;
        }
        ArrayList<Doctor> doctors = departmentByUser.getDoctors();  //通过科室得到医生集合
        if (doctors.size() == 0){
            System.out.println("该科室没有医生~请先为科室添加医生~");
            return;
        }
        while (true) {
            //遍历医生集合 打印各个医生
            for (int i = 0; i < doctors.size(); i++) {
                Doctor doctor = doctors.get(i);
                System.out.println((i + 1) + "、" + doctor.getName());
            }
            System.out.println("请选择上述医生的序号：");
            int command = sc.nextInt();
            if (command < 1 || command > doctors.size()){
                System.out.println("对不起~选择的序号有误~请重新输入喔");
                continue;
            }
            Doctor doctor = doctors.get(command - 1);  //拿到了要排班的医生对象
            ArrayList<Schedule> schedules = doctor.getSchedules();  //将要排班的医生对象中的排班集合取出来
            //开始对上述取到的医生中的排班集合进行设置，保证排班信息永远是：当天的和未来6天的
            updateSchedule(schedules);
            //开始对每天的上午和下午进行排班，遍历所有天，对每天进行修改
            for (int i = 0; i < schedules.size(); i++) {
                Schedule schedule = schedules.get(i);
                updateDoctorSchedule(schedule);
            }
            break;
        }
    }

    //对医生每一天坐诊情况进行设置
    private void updateDoctorSchedule(Schedule schedule) {
        LocalDate today = schedule.getToday();
        System.out.println(today + "的排班信息如下：");
        if (!schedule.isUpdate()){
            System.out.println(today + "未排班");
        }
//        else{
//            System.out.println("上午：");
//            if (schedule.isMorning()){
//                System.out.println("坐诊时间为" + schedule.getMstart() + "-" + schedule.getMend()
//                        + "可预约总人数为" + schedule.getmAppointTotalNumber());
//            }else{
//                System.out.println("休息中~");
//            }
//            System.out.println("下午：");
//            if (schedule.isAfternoon()){
//                System.out.println("坐诊时间为" + schedule.getAstart() + "-" + schedule.getAend()
//                        + "可预约总人数为" + schedule.getaAppointTotalNumber());
//            }else{
//                System.out.println("休息中~");
//            }
//        }

        while (true) {
            System.out.println("是否对" + today + "上午排班？y/n");
            String command1 = sc.next();
            if (command1.equals("y")){
                schedule.setMorning(true);

                System.out.println("上午上班开始时间：(HH:mm:ss)");
                String start1 = sc.next();
                schedule.setMstart(LocalTime.parse(start1));

                System.out.println("结束时间：(HH:mm:ss)");
                String end1 = sc.next();
                schedule.setMend(LocalTime.parse(end1));

                System.out.println("可预约总人数：");
                int num1 = sc.nextInt();
                schedule.setmAppointTotalNumber(num1);
                break;
            }else if (command1.equals("n")){
                schedule.setMorning(false);
                break;
            }else {
                System.out.println("您输入的指令有误请重新输入喔~");
            }
        }

        while (true) {
            System.out.println("是否对" + today + "下午排班？y/n");
            String command2 = sc.next();
            if (command2.equals("y")){
                schedule.setAfternoon(true);

                System.out.println("开始时间：(HH:mm:ss)");
                String start2 = sc.next();
                schedule.setAstart(LocalTime.parse(start2));

                System.out.println("结束时间：(HH:mm:ss)");
                String end2 = sc.next();
                schedule.setAend(LocalTime.parse(end2));

                System.out.println("可预约总人数：");
                int num2 = sc.nextInt();
                schedule.setaAppointTotalNumber(num2);
                break;
            }else if (command2.equals("n")){
                schedule.setAfternoon(false);
                break;
            }else {
                System.out.println("您输入的指令有误请重新输入喔~");
            }
        }

        if (schedule.isMorning() || schedule.isAfternoon()){
            schedule.setUpdate(true);
        }
    }


    private void updateSchedule(ArrayList<Schedule> schedules) {
        //如果医生没有排过班，就对其从当天开始往后排六天对象添加到集合中去
        if (schedules.size() == 0){
            for (int i = 0; i < 7; i++) {
                Schedule schedule = new Schedule();
                LocalDate today = LocalDate.now();
                schedule.setToday(today.plusDays(i));  //从当天开始，然后往后加，一共加六天
                schedules.add(schedule);
            }
            return;
        }

        //排除过期的时间，也就是医生已经排过班，然后干了几天之后，
        // 要把干过的日期排除掉，再往后加上新的日期，保证排班一直满足是当天和未来6天

        //排除过期日期如下：
        for (int i = 0; i < schedules.size(); i++) {
            Schedule schedule = schedules.get(i);
            LocalDate today = schedule.getToday();  //得到当前索引的当天日期
            LocalDate now = LocalDate.now();  //得到现在的此时当天日期
            if (now.equals(today)){
                break;
            }
            if(today.isBefore(now)){  //如果当前索引的当天日期是在此时当天日期之前，说明已经排班干了几天了将这干了的排班移除
                schedules.remove(schedule);
                i--;  //防止漏删
            }
        }

        //删完之后过期日期之后，要增加后面日期到排班集合中去，就是为了保证排班日期始终是当天和未来6天
        //假设删完后排班集合中还有三个[s1,s2,s3,]
        int size = schedules.size();  //删完后 排班集合的长度
        Schedule scheduleLast = schedules.get(size - 1);  //得到最后一个位置索引的排班对象
        LocalDate last = scheduleLast.getToday();  //得到最后一个索引位置的日期
        for (int i = 0; i < 7 - size; i++) {  //补全排班集合后面的对象
            LocalDate date = last.plusDays(i + 1);
            Schedule schedule = new Schedule();
            schedule.setToday(date);
            schedules.add(schedule);
        }
    }



    //通过用户给医生选择科室
    private Department getDepartmentByUser(){

        if (departments.size() == 0){
            System.out.println("现在还没有科室，无法录入医生，请先添加科室~");
            return null;
        }

        while (true) {
            for (int i = 0; i < departments.size(); i++) {
                Department department = departments.get(i);
                System.out.println((i+1) + "、" + department.getName());
            }
            System.out.println("请选择医生所属的上述科室序号：");
            int command = sc.nextInt();
            if (command < 1 || command > departments.size()){
                System.out.println("对不起~您输入的序号有误~请重新输入喔");
                continue;
            }
            Department department = departments.get(command - 1);
            return department;
        }
    }

    //添加医生
    private void addDoctor() {
        System.out.println("~~添加医生~~");
        Doctor doctor = new Doctor();
        //调用由用户选择科室方法得到科室
        Department department = getDepartmentByUser();
        if (department == null){
            return;
        }

        doctor.setDepartmentName(department.getName());

        System.out.println("请输入医生的姓名：");
        String name = sc.next();
        doctor.setName(name);

        System.out.println("年龄：");
        int age = sc.nextInt();
        doctor.setAge(age);

        while (true) {
            System.out.println("性别：");
            char sex = sc.next().charAt(0);
            if (sex == '男' || sex == '女'){
                doctor.setSex(sex);
                break;
            }else{
                System.out.println("您输入的性别有误~请重新输入喔");
            }
        }

        //用于生成医生的id，随机64位的英文字母和数字和横杠组成的，重复概率很小，就不判断重复问题了用于简化
        String id = UUID.randomUUID().toString();
        doctor.setDoctorId(id);

        System.out.println("特长：");
        String specialty = sc.next();
        doctor.setSpecialty(specialty);

        while (true) {
            System.out.println("入职时间：(格式：yyyy-MM-dd)");
            String sdate = sc.next();

            if (Formatter(sdate)){
            LocalDate date = LocalDate.parse(sdate);
            doctor.setDate(date);
            break;
            }else{
                System.out.println("您输入的格式有误~请重新输入喔~");
            }
        }

        department.getDoctors().add(doctor);
        System.out.println("录入医生到该科室成功~");

    }

    //用于判断年月日格式合不合理，合理返回true
    private boolean Formatter(String d){
        if(d.matches("(\\d{4}-[0][1-9]-[0-2][0-9])|(\\d{4}-[0][1-9]-[3][0-1])|(\\d{4}-[1][0-2]-[0-2][0-9])|(d{4}-[1][0-2]-[3][0-1])")){
            return true;
        }
        return false;
    }

    //添加科室
    private void addDepartment() {
        System.out.println("~~添加科室~~");
        OUT:
        while (true) {
            System.out.println("请输入科室的名字：");
            String name = sc.next();
            for (int i = 0; i < departments.size(); i++) {
                Department department = departments.get(i);
                if (name.equals(department.getName())){
                    System.out.println("对不起~该科室的名字重复了，请重新输入~");
                    continue OUT;
                }
            }
            Department department = new Department();
            department.setName(name);
            departments.add(department);
            System.out.println("添加科室成功~");
            break;
        }
    }


}
